package com.ruoyi.reportInfo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.reportInfo.domain.*;
import com.ruoyi.reportInfo.mapper.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.reportInfo.domain.bo.IndustrialParkBo;
import com.ruoyi.reportInfo.domain.vo.IndustrialParkVo;
import com.ruoyi.reportInfo.service.IIndustrialParkService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 园区信息Service业务层处理
 *
 * @author yangzhen
 * @date 2025-11-24
 */
@RequiredArgsConstructor
@Service
public class IndustrialParkServiceImpl implements IIndustrialParkService {

    private final IndustrialParkMapper baseMapper;

    private final IndustrialLogisticsCompanyLineOperationMapper industrialLogisticsCompanyLineOperationMapper;
    private final IndustrialLogisticsCompanyMapper industrialLogisticsCompanyMapper;
    private final IndustrialStationMapper industrialStationMapper;
    private final IndustrialStationOperationInfoMapper industrialStationOperationInfoMapper;


    /**
     * 查询园区信息
     */
    @Override
    public IndustrialParkVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询园区信息列表
     */
    @Override
    public TableDataInfo<IndustrialParkVo> queryPageList(IndustrialParkBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IndustrialPark> lqw = buildQueryWrapper(bo);
        Page<IndustrialParkVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询园区信息列表
     */
    @Override
    public List<IndustrialParkVo> queryList(IndustrialParkBo bo) {
        LambdaQueryWrapper<IndustrialPark> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<IndustrialPark> buildQueryWrapper(IndustrialParkBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IndustrialPark> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getParkName()), IndustrialPark::getParkName, bo.getParkName());
        lqw.eq(StringUtils.isNotBlank(bo.getParkType()), IndustrialPark::getParkType, bo.getParkType());
        lqw.eq(StringUtils.isNotBlank(bo.getMainGoodsType()), IndustrialPark::getMainGoodsType, bo.getMainGoodsType());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorCompany()), IndustrialPark::getOperatorCompany, bo.getOperatorCompany());
        lqw.eq(StringUtils.isNotBlank(bo.getUnifiedSocialCode()), IndustrialPark::getUnifiedSocialCode, bo.getUnifiedSocialCode());
        lqw.eq(bo.getArea() != null, IndustrialPark::getArea, bo.getArea());
        lqw.eq(StringUtils.isNotBlank(bo.getBelongProject()), IndustrialPark::getBelongProject, bo.getBelongProject());
        lqw.eq(bo.getStorageArea() != null, IndustrialPark::getStorageArea, bo.getStorageArea());
        lqw.eq(bo.getColdArea() != null, IndustrialPark::getColdArea, bo.getColdArea());
        lqw.eq(bo.getRailwayNum() != null, IndustrialPark::getRailwayNum, bo.getRailwayNum());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), IndustrialPark::getAddress, bo.getAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getLongitude()), IndustrialPark::getLongitude, bo.getLongitude());
        lqw.eq(StringUtils.isNotBlank(bo.getLatitude()), IndustrialPark::getLatitude, bo.getLatitude());
        lqw.eq(StringUtils.isNotBlank(bo.getManager()), IndustrialPark::getManager, bo.getManager());
        lqw.eq(StringUtils.isNotBlank(bo.getManagerContact()), IndustrialPark::getManagerContact, bo.getManagerContact());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList1()), IndustrialPark::getFileList1, bo.getFileList1());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList2()), IndustrialPark::getFileList2, bo.getFileList2());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList3()), IndustrialPark::getFileList3, bo.getFileList3());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList4()), IndustrialPark::getFileList4, bo.getFileList4());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList5()), IndustrialPark::getFileList5, bo.getFileList5());
        lqw.eq(bo.getDataStatus() != null, IndustrialPark::getDataStatus, bo.getDataStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getDataSources()), IndustrialPark::getDataSources, bo.getDataSources());
        lqw.eq(bo.getCollectDate() != null, IndustrialPark::getCollectDate, bo.getCollectDate());
        return lqw;
    }

    /**
     * 新增园区信息
     */
    @Override
    public Boolean insertByBo(IndustrialParkBo bo) {
        IndustrialPark add = BeanUtil.toBean(bo, IndustrialPark.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改园区信息
     */
    @Override
    public Boolean updateByBo(IndustrialParkBo bo) {
        IndustrialPark update = BeanUtil.toBean(bo, IndustrialPark.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(IndustrialPark entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除园区信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TableDataInfo<IndustrialParkVo> industrialParkPageList(IndustrialParkBo bo, PageQuery pageQuery) {

        // 获取分页园区数据
        LambdaQueryWrapper<IndustrialPark> lqw = buildQueryWrapper(bo);
        Page<IndustrialParkVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        // 当前年份
        int currentYear = LocalDate.now().getYear();

        // ------ 遍历每个园区并补充统计数据 ------
        for (IndustrialParkVo parkVo : result.getRecords()) {

            String parkId = parkVo.getId();

            /*-----------------------------------------
             * 1. 查询园区关联的场站信息
             *-----------------------------------------*/
            List<IndustrialStation> stationList =
                industrialStationMapper.selectList(
                    new LambdaQueryWrapper<IndustrialStation>()
                        .eq(IndustrialStation::getBelongParkId, parkId)
                );

            List<String> stationIds = stationList.stream()
                .map(IndustrialStation::getId)
                .collect(Collectors.toList());

            // 场站数量
            parkVo.setStationCount(stationIds.size());

            /*-----------------------------------------
             * 2. 查询这些场站对应的当年运营信息（货运量）
             *-----------------------------------------*/
            BigDecimal stationAnnualFreight = BigDecimal.ZERO;

            if (!stationIds.isEmpty()) {
                List<IndustrialStationOperationInfo> stationOpList =
                    industrialStationOperationInfoMapper.selectList(
                        new LambdaQueryWrapper<IndustrialStationOperationInfo>()
                            .in(IndustrialStationOperationInfo::getStationId, stationIds)
                            .apply("YEAR(report_collect_date) = {0}", currentYear)
                    );

                stationAnnualFreight = stationOpList.stream()
                    .map(IndustrialStationOperationInfo::getFreightVolume)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            parkVo.setStationAnnualFreightVolume(stationAnnualFreight);

            /*-----------------------------------------
             * 3. 查询园区关联的企业信息
             *-----------------------------------------*/
            List<IndustrialLogisticsCompany> companyList =
                industrialLogisticsCompanyMapper.selectList(
                    new LambdaQueryWrapper<IndustrialLogisticsCompany>()
                        .eq(IndustrialLogisticsCompany::getBelongParkId, parkId)
                );

            List<String> companyIds = companyList.stream()
                .map(IndustrialLogisticsCompany::getId)
                .collect(Collectors.toList());

            // 企业数量
            parkVo.setCompanyCount(companyIds.size());

            /*-----------------------------------------
             * 4. 查询企业专线运营信息（当年货运量）
             *-----------------------------------------*/
            BigDecimal companyAnnualFreight = BigDecimal.ZERO;

            if (!companyIds.isEmpty()) {
                List<IndustrialLogisticsCompanyLineOperation> lineOpList =
                    industrialLogisticsCompanyLineOperationMapper.selectList(
                        new LambdaQueryWrapper<IndustrialLogisticsCompanyLineOperation>()
                            .in(IndustrialLogisticsCompanyLineOperation::getCompanyId, companyIds)
                            .apply("YEAR(report_collect_date) = {0}", currentYear)
                    );

                companyAnnualFreight = lineOpList.stream()
                    .map(IndustrialLogisticsCompanyLineOperation::getFreightVolume)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            parkVo.setCompanyAnnualFreightVolume(companyAnnualFreight);
        }

        return TableDataInfo.build(result);
    }

}
